﻿using System;
using System.Collections.Generic;
using System.Reflection;
using FBEntities.FBConnections.User;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using XDAFacebook;
using XFControls.Utils;

namespace FBEntities.FBObjects.User
{
    public class FBPerson : IFBUpdatable
    {
        //public event EventHandler FinishParse;
        public bool Parsed;

        public string about;
        public FBActivities activities;
        public FBAlbums albums;
        public string bio;
        public string birthday;
        public FBBooks books;
        public FBCheckins checkins;
        public List<FBEducation> education;
        public string email;
        public FBEvents events;
        public FBFeed feed;
        public string first_name;
        public FBFriends friends;
        public FBCheckins friendsCheckins;
        public string gender;
        public FBGroups groups;
        public FBHome home;
        public FBObject hometown;
        public string id;
        public FBInbox inbox;
        public string[] interested_in;
        public FBInterests interests;
        public string last_name;
        public FBLikes likes;
        public string link;
        public FBLinks links;
        public FBObject location;
        public string[] meeting_for;
        public FBMovies movies;
        public FBMusic music;
        public string name;
        public FBNotes notes;
        public FBInbox outbox;
        public FBPhotos photos;
        public FBPicture picture;
        public string political;
        public FBPosts posts;
        public string quotes;
        public string relationship_status;
        public string religion;
        public FBPerson significant_other;
        public FBStatuses statuses;
        public FBTagged tagged;
        public FBTelevision television;
        public int timezone;
        public DateTime updated_time;
        public bool verified;
        public string website;
        public List<FBWork> work;

        public FBPerson()
        {
            Parsed = false;
            work = new List<FBWork>();
            education = new List<FBEducation>();
        }

        [JsonIgnore]
        public FBHome Home
        {
            get { return home ?? (home = new FBHome()); }
            protected set { home = value; }
        }

        [JsonIgnore]
        public FBFeed Feed
        {
            get { return feed ?? (feed = new FBFeed()); }
            protected set { feed = value; }
        }

        [JsonIgnore]
        public FBTagged Tagged
        {
            get { return tagged ?? (tagged = new FBTagged()); }
            protected set { tagged = value; }
        }

        [JsonIgnore]
        public FBPosts Posts
        {
            get { return posts ?? (posts = new FBPosts()); }
            protected set { posts = value; }
        }

        [JsonIgnore]
        public FBPicture Picture
        {
            get { return picture ?? (picture = new FBPicture(id)); }
            protected set { picture = value; }
        }

        [JsonIgnore]
        public FBFriends Friends
        {
            get
            {
                if (friends == null)
                {
                    friends = new FBFriends();
                    friends.ParseCached();
                }
                return friends;
            }
            protected set { friends = value; }
        }

        [JsonIgnore]
        public FBActivities Activities
        {
            get { return activities ?? (activities = new FBActivities()); }
            protected set { activities = value; }
        }

        [JsonIgnore]
        public FBInterests Interests
        {
            get { return interests ?? (interests = new FBInterests()); }
            protected set { interests = value; }
        }

        [JsonIgnore]
        public FBMusic Music
        {
            get { return music ?? (music = new FBMusic()); }
            protected set { music = value; }
        }

        [JsonIgnore]
        public FBBooks Books
        {
            get { return books ?? (books = new FBBooks()); }
            protected set { books = value; }
        }

        [JsonIgnore]
        public FBMovies Movies
        {
            get { return movies ?? (movies = new FBMovies()); }
            protected set { movies = value; }
        }

        [JsonIgnore]
        public FBTelevision Television
        {
            get { return television ?? (television = new FBTelevision()); }
            protected set { television = value; }
        }

        [JsonIgnore]
        public FBLikes Likes
        {
            get { return likes ?? (likes = new FBLikes()); }
            protected set { likes = value; }
        }

        [JsonIgnore]
        public FBPhotos Photos
        {
            get { return photos ?? (photos = new FBPhotos()); }
            protected set { photos = value; }
        }

        [JsonIgnore]
        public FBAlbums Albums
        {
            get { return albums ?? (albums = new FBAlbums()); }
            protected set { albums = value; }
        }

        [JsonIgnore]
        public FBStatuses Statuses
        {
            get { return statuses ?? (statuses = new FBStatuses()); }
            protected set { statuses = value; }
        }

        [JsonIgnore]
        public FBLinks Links
        {
            get { return links ?? (links = new FBLinks()); }
            protected set { links = value; }
        }

        [JsonIgnore]
        public FBNotes Notes
        {
            get { return notes ?? (notes = new FBNotes()); }
            protected set { notes = value; }
        }

        [JsonIgnore]
        public FBEvents Events
        {
            get { return events ?? (events = new FBEvents()); }
            protected set { events = value; }
        }

        [JsonIgnore]
        public FBInbox Inbox
        {
            get { return inbox ?? (inbox = new FBInbox()); }
            protected set { inbox = value; }
        }

        [JsonIgnore]
        public FBInbox Outbox
        {
            get { return outbox ?? (outbox = new FBInbox()); }
            protected set { outbox = value; }
        }

        [JsonIgnore]
        public FBCheckins Checkins
        {
            get { return checkins ?? (checkins = new FBCheckins()); }
            protected set { checkins = value; }
        }

        [JsonIgnore]
        public FBCheckins FriendsCheckins
        {
            get
            {
                if (friendsCheckins == null)
                    friendsCheckins = new FBCheckins();

                if (!friendsCheckins.Parsed)
                {
                    string url = "https://graph." + Settings.Domain + ".com/search?type=checkin&" + FBParseUtilities.authKey;

                    var wrapper = new WebDownloaderWrapper(url);
                    string json = wrapper.Download();
                    if (string.IsNullOrEmpty(json))
                        return null;

                    JObject o = JObject.Parse(json);
                    friendsCheckins.Parse(o);
                }

                return friendsCheckins;
            }
            set { friendsCheckins = value; }
        }

        [JsonIgnore]
        public FBGroups Groups
        {
            get { return groups ?? (groups = new FBGroups()); }
            set { groups = value; }
        }

        #region IFBUpdatable Members

        public void Parse(JObject o)
        {
            if (o == null) return;
            Parsed = true;
            FBParseUtilities.Parse(o, this);

            if (Updated != null)
                Updated(this, new EventArgs());
        }

        public void Update()
        {
            if (Updated != null)
                Updated(this, new EventArgs());
        }

        public event UpdateEventHandler Updated;

        #endregion

        public WebDownloaderWrapper UpdateStatus(string status)
        {
            return FBParseUtilities.PostTextREST(id, "status.set", new[] { "status", status });
        }

        public void Poke()
        {
            //throw new NotImplementedException();
        }

        public WebDownloaderWrapper GetWebDownloader()
        {
            if (string.IsNullOrEmpty(id))
                return null;

            string url = "https://graph." + Settings.Domain + ".com/" + id + "?" + FBParseUtilities.authKey;

            return new WebDownloaderWrapper(url);
        }
    }
}